package com.leetcode;

import javafx.util.Pair;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 279. 完全平方数
 * 转换成图论广度优先遍历，BFS即最短路径
 *
 * @author fy
 * @date 2022-04-16
 */
public class Solution279_1 {

    public int numSquares(int n) {
        // 图的广度优先遍历， 存入的是节点及到达该节点所经过的路径长度
        Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
        queue.offer(new Pair<>(n, 0));

        // 记录该节点是否已经访问过, 已经访问过就不再推入栈中，降低计算量
        boolean[] visited = new boolean[n + 1];
        visited[n] = true;

        while (!queue.isEmpty()) {
            // 取出当前栈顶节点
            Pair<Integer, Integer> pair = queue.poll();
            Integer num = pair.getKey();
            Integer path = pair.getValue();
            for (int i = 1; ; i++) {
                int newNum = num - i * i;
                if (newNum < 0) {
                    break;
                }
                // 如果还能减去一个完全平方数的，并且刚好为0，则直接返回路径长度
                if (newNum == 0) {
                    return path + 1;
                }
                // 如果没有访问过，并且路径还能减去一个完全平方数的和，则将其推入栈中，下次再计算
                if (!visited[newNum]) {
                    queue.offer(new Pair<>(newNum, path + 1));
                    visited[newNum] = true;
                }
            }
        }
        throw new RuntimeException("error n");
    }

}
